/**
 * 
 */
package furniture.viewer;

import javax.vecmath.Point3d;

import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.ecore.resource.ResourceSet;
import org.eclipse.swt.graphics.RGB;

import furniture.Addition;
import furniture.Board;
import furniture.Furniture;
import furniture.Literal;
import furniture.Multiplication;
import furniture.NamedValue;
import furniture.Part;
import furniture.RectangularBoard;
import furniture.Value;
import furniture.ValueRef;
import furniture.items3d.model.CuboidPrimitive;
import furniture.items3d.model.LayedPrimitive;
import furniture.items3d.model.LayingModel;

/**
 * @author balage
 *
 */
public class FurnitureModeler {

	public LayingModel buildModel(ResourceSet rs){
		LayingModel lm = new LayingModel();
		for(Resource r : rs.getResources()){
			for(EObject eo : r.getContents()){
				if (eo instanceof Furniture){
					for(Part p : ((Furniture) eo).getParts()){
						lm.addPrimitive(getPrimitive(p));
					}
				}
			}
		}
		return lm;
	}
	
	public LayedPrimitive getPrimitive(Part p){
		Board b = p.getBoard();
		Point3d p3 = new Point3d(
				resolveValue(p.getX()),
				resolveValue(p.getY()),
				resolveValue(p.getZ()));
		double thickness = resolveValue(b.getThickness());
		
		if (b instanceof RectangularBoard){
			CuboidPrimitive cp = new CuboidPrimitive();
			
			cp.color = new RGB(100, 100, 100);
			double x = resolveValue(((RectangularBoard) b).getX());
			double y = resolveValue(((RectangularBoard) b).getY());
			
			switch(p.getPlacement()){
			case FACE:
				cp.startpoint = new Point3d(0,0,0);
				cp.endpoint = new Point3d(x,y, thickness);
				break;
			case VERTICAL:
				cp.startpoint = new Point3d(0,0,0);
				cp.endpoint = new Point3d(thickness, x, y);
				break;
			case HORIZONTAL:
				cp.startpoint = new Point3d(0,0,0);
				cp.endpoint = new Point3d(x, thickness, y);
				break;
			}
			
			cp.startpoint.add(p3);
			cp.endpoint.add(p3);
			return cp;
		}
		
		return null;
	}
	
	public double resolveValue(Value v){
		if (v instanceof Literal){
			return ((Literal) v).getValue();
		}
		if (v instanceof NamedValue){
			return resolveValue(((NamedValue) v).getValue());
		}
		if (v instanceof ValueRef){
			return resolveValue(((ValueRef) v).getRef());
		}
		if (v instanceof Addition){
			double val = 0;
			for(Value vv : ((Addition) v).getValues()){
				val += resolveValue(vv);
			}
			return val;
		}
		if (v instanceof Multiplication){
			double val = 1;
			for(Value vv : ((Multiplication) v).getValues()){
				val *= resolveValue(vv);
			}
			return val;
		}
		
		return 0;
	}
	
}
